import { isDate, isPlainObject, isURLSearchParams } from './util'

interface URLOrigin {
    protocol: string
    host: string
}

// 特殊字符处理
function encode(val: string): string {
    return encodeURIComponent(val)
        .replace(/%40/g, '@')
        .replace(/%3A/gi, ':')
        .replace(/%24/g, '$')
        .replace(/%2C/gi, ',')
        .replace(/%20/g, '+')
        .replace(/%5B/gi, '[')
        .replace(/%5D/gi, ']')
}
// url 必须  参数 可选
export function buildURL(
    url: string,
    params?: any,
     paramsSerializer?: (params: any) => string
): string {

    // 如果 params 没有
    // !null:true !undefined:true
    if (!params) {
        return url
    }


    // 自定义 参数 解析 
    let serializedParams
    if (paramsSerializer) {
        // 是否 有自定义规则
        serializedParams = paramsSerializer(params)
    } else if (isURLSearchParams(params)) {
        // 是否 是 search url params 类型
        serializedParams = params.toString()
    } else {
        // 处理params 
        const parts: string[] = []

        Object.keys(params).forEach(key => {
          const val = params[key]
          if (val === null || typeof val === 'undefined') {
            return
          }
          let values = []
          if (Array.isArray(val)) {
            values = val
            key += '[]'
          } else {
            values = [val]
          }
          values.forEach(val => {
            if (isDate(val)) {
              val = val.toISOString()
            } else if (isPlainObject(val)) {
              val = JSON.stringify(val)
            }
            parts.push(`${encode(key)}=${encode(val)}`)
          })
        })
    
        serializedParams = parts.join('&')

    }



    // 拆解 parts
    //serializedParams = parts.join('&')
    if (serializedParams) {
        // 舍弃 哈希
        const markIndex = url.indexOf('#')
        if (markIndex !== -1) {
            url = url.slice(0, markIndex)
        }


        // 参数拼接
        url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
    }

    return url
}

// 跨站请求伪造 
export function isURLSameOrigin(requestURL: string): boolean {
    const parsedOrigin = resolveURL(requestURL)
    return (
        parsedOrigin.protocol === currentOrigin.protocol && parsedOrigin.host === currentOrigin.host
    )
}

// 判断 同源策略
const urlParsingNode = document.createElement('a')
const currentOrigin = resolveURL(window.location.href)

function resolveURL(url: string): URLOrigin {
    urlParsingNode.setAttribute('href', url)
    const { protocol, host } = urlParsingNode

    return {
        protocol,
        host
    }
}


export function isAbsoluteURL(url: string): boolean {
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}

export function combineURL(baseURL: string, relativeURL?: string): string {
  return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}


